home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / p4 / p4-1_2c.lha / p4-1.2c / messages / systest.c < prev    next >
C/C++ Source or Header  |  1993-05-25  |  11KB  |  473 lines

  1. #include "p4.h"
  2.  
  3. extern void slave();
  4.  
  5. int main(argc,argv)
  6.      int argc;
  7.      char **argv;
  8. /*
  9.   Generic SPMD master program .. just creates environment
  10.   and then calls slave, just as the slaves do.
  11.   This probably does NOT do what U want on the iPSC.
  12. */
  13. {
  14.   p4_initenv(&argc,argv);
  15.   p4_create_procgroup();
  16.  
  17.   slave();
  18.  
  19.   p4_wait_for_end();
  20. }
  21.  
  22. #define MAX2(a,b) (((a)>(b)) ? (a) : (b))
  23.  
  24. static void Hello();
  25. static void Ring();
  26. static void Stress();
  27. static void Globals();
  28. static int  GlobalReadInteger();
  29.  
  30. extern void synchronize();
  31.  
  32. void slave()
  33. /*
  34.   Test and time aspects of the system.
  35. */
  36. {
  37.   int me = p4_get_my_id();
  38.   int option;
  39.  
  40.   (void) p4_soft_errors(FALSE);  /* This should be the default */
  41.  
  42.   p4_dprintfl(00,"%d is alive on a %s\n",me,p4_machine_type());
  43.   fflush(stdout);
  44.  
  45.   while (1) {
  46.  
  47.     synchronize(1000);
  48.     /* sleep(1); */          /* To allow output to catch up */
  49.  
  50.   again:
  51.     if (me == 0) {
  52.       /* Read user input for action */
  53.       (void) printf("\nOptions: 0=quit, 1=Hello, 2=Ring, 3=Stress, ");
  54.       (void) printf("4=Globals : ");
  55.       (void) fflush(stdout);
  56.     }
  57.     option = GlobalReadInteger();
  58.     if ( (option < 0) || (option > 4) )
  59.       goto again;
  60.  
  61.     switch (option) {
  62.     case 0:
  63.       return;
  64.  
  65.     case 1:
  66.       Hello();
  67.       break;
  68.  
  69.     case 2:
  70.       Ring();
  71.       break;
  72.  
  73.     case 3:
  74.       Stress();
  75.       break;
  76.  
  77.     case 4:
  78.       Globals();
  79.       break;
  80.  
  81.     default:
  82.       p4_error("systest: invalid option", option);
  83.       break;
  84.     }
  85.   }
  86. }
  87.  
  88. static void Hello()
  89. /*
  90.   Everyone exchanges a hello message with everyone else.
  91.   The hello message just comprises the sending and target nodes.
  92. */
  93. {
  94.   int nproc = p4_num_total_ids();
  95.   int me = p4_get_my_id();
  96.   int type = 1;
  97.   int buffer[2], node, *input, length;
  98.  
  99.   if (me == 0) {
  100.     (void) printf("\nHello test ... show network integrity\n----------\n\n");
  101.     (void) fflush(stdout);
  102.   }
  103.  
  104.   for (node = 0; node<nproc; node++) {
  105.     if (node != me) {
  106.       buffer[0] = me;
  107.       buffer[1] = node;
  108.       (void) p4_sendx(type,node,(char *) buffer,sizeof buffer,P4INT);
  109.       input = (int *) NULL;
  110.       (void) p4_recv(&type, &node, (char **) &input, &length);
  111.  
  112.       if ( (input[0] != node) || (input[1] != me) ) {
  113.     (void) fprintf(stderr, "Hello: %d!=%d or %d!=%d\n",
  114.                input[0], node, input[1], me);
  115.     p4_error("Mismatch on hello process ids", node);
  116.       }
  117.  
  118.       (void) p4_dprintfl(00,"Hello from %d to %d\n", me, node);
  119.       (void) fflush(stdout);
  120.     }
  121.   }
  122. }
  123.  
  124. static void Ring()
  125.      /* Time passing a message round a ring */
  126. {
  127.   int me = p4_get_my_id();
  128.   int nproc = p4_num_total_ids();
  129.   int type = 4;
  130.   int left = (me + nproc - 1) % nproc;
  131.   int right = (me + 1) % nproc;
  132.   char *buffer;
  133.   int start, lenbuf, used, max_len, *msg, msg_len;
  134.   double rate;
  135.   p4_usc_time_t start_ustime, end_ustime, used_ustime;
  136.  
  137.   /* Find out how big a message to use */
  138.  
  139.   if (me == 0) {
  140.     (void) printf("\nRing test ... time network performance\n---------\n\n");
  141.     (void) printf("Input maximum message size: ");
  142.     (void) fflush(stdout);
  143.   }
  144.   max_len = GlobalReadInteger();
  145.   if ( (max_len <= 0) || (max_len >= 4*1024*1024) )
  146.     max_len = 512*1024;
  147.   if (me == 0)
  148.     if ( (buffer = p4_shmalloc((unsigned) max_len)) == (char *) NULL)
  149.       p4_error("Ring: failed to allocate buffer",max_len);
  150.  
  151.   type = 5;
  152.  
  153.   lenbuf = 1;
  154.   while (lenbuf <= max_len) {
  155.  
  156.     start = p4_clock();
  157.     start_ustime = p4_ustimer();
  158.     if (me == 0) {
  159.       (void) p4_send(type, left, buffer, lenbuf);
  160.       msg = (int *) NULL;
  161.       (void) p4_recv(&type, &right, (char **) &msg, &msg_len);
  162.       p4_msg_free((char *) msg);
  163.     }
  164.     else {
  165.       msg = (int *) NULL;
  166.       (void) p4_recv(&type, &right, (char **) &msg, &msg_len);
  167.       (void) p4_send(type, left, (char *) msg, msg_len);
  168.       p4_msg_free((char *) msg);
  169.     }
  170.     used = p4_clock() - start;
  171.     used_ustime = p4_ustimer() - start_ustime;
  172.  
  173.     if (used > 0)
  174.       rate = 1.0e-3 * (double) (nproc * lenbuf) / (double) used;
  175.     else
  176.       rate = 0.0;
  177.     if (me == 0)
  178.       (void) printf("len=%d bytes, used=%d ms, used_us=%d rate=%f Mbytes/sec\n",
  179.             lenbuf, used, used_ustime, rate);
  180.     
  181.     lenbuf *= 2;
  182.   }
  183.  
  184.   if (me == 0)
  185.     (void) p4_shfree(buffer);
  186.  
  187. }
  188.  
  189. double ranf()
  190. /* Returns ran # uniform in (0,1) ... probably rather bad statistics. */
  191. {
  192.   static unsigned long seed = 54321;
  193.  
  194.   seed = seed * 1812433253 + 12345;
  195.   return (seed & 0x7fffffff) * 4.6566128752458e-10;
  196. }
  197.  
  198. static void RandList(lo, hi, list, n)
  199.      int lo, hi, *list, n;
  200. /*
  201.   Fill list with n random integers between lo & hi inclusively
  202. */
  203. {
  204.   int i, ran;
  205.   double dran;
  206.  
  207.   for (i=0; i<n; i++) {
  208.     dran = ranf();
  209.     ran = lo + (int) (dran * (double) (hi-lo+1));
  210.     if (ran < lo)
  211.       ran = lo;
  212.     if (ran > hi)
  213.       ran = hi;
  214.     list[i] = ran;
  215.   }
  216. }
  217.  
  218. static void Stress()
  219. /*
  220.   Stress the system by passing messages between a randomly selected
  221.   list of nodes
  222. */
  223. {
  224. #define N_LEN 10
  225. #ifdef NCUBE
  226.   /* ncube does not handle msgs larger than 
  227.      32K at present (see nwrite) */
  228.   static int len[N_LEN] = {0,1,2,4,8,4096,8192,16384,32768,32768};
  229. #else
  230.   static int len[N_LEN] = {0,1,2,4,8,4096,8192,16384,32768,65536};
  231. #endif
  232.   int me = p4_get_my_id();
  233.   int nproc = p4_num_total_ids();
  234.   int zero = 0;
  235.   int type, lenbuf, i, j, from, to;
  236.   int *list_i, *list_j, *list_n;
  237.   char *buffer;
  238.   int n_stress, mod, *msg, msg_len;
  239.  
  240.  
  241.   type = 6;
  242.   if (me == 0) {
  243.     (void) printf("\nStress test ... randomly exchange messages\n-----------");
  244.     (void) printf("\n\nInput no. of messages: ");
  245.     (void) fflush(stdout);
  246.   }
  247.   n_stress = GlobalReadInteger();
  248.   if ( (n_stress <= 0) || (n_stress > 100000) )
  249.     n_stress = 1000;
  250.   p4_dprintfl(00,"n_stress=%d\n",n_stress);
  251.  
  252.   lenbuf = n_stress * sizeof(int);
  253.  
  254.   if (!(buffer = p4_shmalloc((unsigned) len[N_LEN-1])))
  255.     p4_error("Stress: failed to allocate buffer", len[N_LEN-1]);
  256.  
  257.   type = 7;
  258.   if (me == 0) { /* Make random list of pairs and message lengths */
  259.     if (!(list_i = (int *) p4_shmalloc((unsigned) lenbuf)))
  260.       p4_error("Stress: failed to allocate list_i",lenbuf);
  261.     if (!(list_j = (int *) p4_shmalloc((unsigned) lenbuf)))
  262.       p4_error("Stress: failed to allocate list_j",lenbuf);
  263.     if (!(list_n = (int *) p4_shmalloc((unsigned) lenbuf)))
  264.       p4_error("Stress: failed to allocate list_n",lenbuf);
  265.  
  266.     RandList((int) 0, nproc-1, list_i, n_stress);
  267.     RandList((int) 0, nproc-1, list_j, n_stress);
  268.     RandList((int) 0, N_LEN-1, list_n, n_stress);
  269.     for (i=0; i<n_stress; i++)
  270.       list_n[i] = len[list_n[i]];
  271.     p4_broadcastx(type, (char *) list_i, lenbuf, P4INT);
  272.     p4_broadcastx(type, (char *) list_j, lenbuf, P4INT);
  273.     p4_broadcastx(type, (char *) list_n, lenbuf, P4INT);
  274.   }
  275.   else {
  276.     list_i = (int *) NULL;
  277.     (void) p4_recv(&type, &zero, (char **) &list_i, &msg_len);
  278.     list_j = (int *) NULL;
  279.     (void) p4_recv(&type, &zero, (char **) &list_j, &msg_len);
  280.     list_n = (int *) NULL;
  281.     (void) p4_recv(&type, &zero, (char **) &list_n, &msg_len);
  282.   }
  283.  
  284.   type = 8;
  285.  
  286.   j = 0;
  287.   mod = (n_stress-1)/10 + 1;
  288.   for (i=0; i < n_stress; i++) {
  289.  
  290.     from   = list_i[i];
  291.     to     = list_j[i];
  292.     lenbuf = list_n[i];
  293.  
  294.     /* P4 can send to self 
  295.     if (from == to)
  296.       continue; */
  297.  
  298.     if ( (me == 0) && (j%mod == 0) ) {
  299.       (void) printf("Stress: test=%ld: from=%ld, to=%ld, len=%ld\n",
  300.             i, from, to, lenbuf);
  301.       (void) fflush(stdout);
  302.     }
  303.  
  304.     j++;  /* Needed when skipping send to self */
  305.  
  306.     if (from == me)
  307.       (void) p4_send(type, to, buffer, lenbuf);
  308.  
  309.     if (to == me) {
  310.       msg = (int *) NULL;
  311.       (void) p4_recv(&type, &from, (char **) &msg, &msg_len);
  312.       p4_msg_free((char *) msg);
  313.       if (msg_len != lenbuf)
  314.     p4_error("Stress: invalid message length on receive",lenbuf);
  315.     }
  316.   }
  317.  
  318.   (void) p4_shfree(buffer);
  319.   if (me == 0) {
  320.     (void) p4_shfree((char *) list_n);
  321.     (void) p4_shfree((char *) list_j);
  322.     (void) p4_shfree((char *) list_i);
  323.   }
  324.   else {
  325.     (void) p4_msg_free((char *) list_n);
  326.     (void) p4_msg_free((char *) list_j);
  327.     (void) p4_msg_free((char *) list_i);
  328.   }
  329. }
  330.  
  331. static int GlobalReadInteger()
  332. /*
  333.   Process zero reads an integer from stdin and broadcasts
  334.   to everyone else
  335. */
  336. {
  337.   int value, *msg, msg_len, type=999,zero=0;
  338.  
  339.   if (p4_get_my_id() == 0) {
  340.     if (scanf("%d", &value) != 1)
  341.       p4_error("failed reading integer value from stdin", -1);
  342.  
  343.     p4_broadcastx(type, (char *) &value, sizeof value,P4INT);
  344.   }
  345.   else {
  346.     msg = (int *) NULL;
  347.     (void) p4_recv(&type, &zero, (char **) &msg, &msg_len);
  348.     value = *msg;
  349.     p4_msg_free((char *) msg);
  350.   }
  351.   return value;
  352. }
  353.  
  354. static int CompareVectors(n, a, b)
  355.      int n;
  356.      double *a, *b;
  357. /*
  358.   Return the no. of differences in two vectors allowing for
  359.   numerical roundoff.
  360. */
  361. {
  362. #define ABS(a)   (((a)>=0 ) ? (a) : -(a))
  363.   int nerrs = 0;
  364.   double diff;
  365.  
  366.   while (n--) {
  367.     diff = *a++ - *b++;
  368.     if (ABS(diff) > 1.0e-8)
  369.       nerrs++;
  370.   }
  371.   
  372.   return nerrs;
  373. }
  374.  
  375. static void Globals()
  376. /*
  377.   Test out functioning of the global operations.
  378. */
  379. {
  380.   int nproc = p4_num_total_ids();
  381.   int me = p4_get_my_id();
  382.   int n, i, start, used, nerrs;
  383.   double *a, *b, rate;
  384.  
  385. #define DO(string, op) \
  386.   start = p4_clock(); \
  387.   if (p4_global_op(33, (char *) a, n, sizeof(double), op, P4DBL)) \
  388.     p4_error("p4_global_op failed",n); \
  389.   used = p4_clock()-start; \
  390.   rate = (used>0) ? n/(1.0e+3 * used) : 0.0; \
  391.   nerrs = CompareVectors(n, a, b); \
  392.   if (me == 0) \
  393.     (void) printf("%s, len=%d, used=%d ms, rate=%f Mop/sec, nerrs=%d\n",\
  394.                    string, n, used, rate, nerrs);
  395.  
  396.   if (me == 0) {
  397.     (void) printf("\nGlobal operations test\n----------------------");
  398.     (void) printf("\n\nInput vector length ");
  399.     (void) fflush(stdout);
  400.   }
  401.   n = GlobalReadInteger();
  402.   if ( (n < 0) || (n > 1000000) )
  403.     n = 1000;
  404.  
  405.   if (!(a = (double *) p4_shmalloc((unsigned) (n*sizeof(double)))))
  406.     p4_error("failed to create work space (a)",n);
  407.   if (!(b = (double *) p4_shmalloc((unsigned) (n*sizeof(double)))))
  408.     p4_error("failed to create work space (b)",n);
  409.  
  410.   /* Summation */
  411.  
  412.   for (i=0; i<n; i++) {
  413.     a[i] = i+me;
  414.     b[i] = nproc*i + (nproc*(nproc-1))/2;
  415.   }
  416.   DO("Summation", p4_dbl_sum_op);
  417.  
  418.   /* Maximum */
  419.  
  420.   for (i=0; i<n; i++) {
  421.     a[i] = i+me;
  422.     b[i] = i+nproc-1;
  423.   }
  424.   DO("Maximum", p4_dbl_max_op);
  425.  
  426.   /* Abs Maximum */
  427.  
  428.   for (i=0; i<n; i++) {
  429.     a[i] = i+me - n/2;
  430.     b[i] = MAX2(n/2-i, i+nproc-1-n/2);
  431.   }
  432.   DO("Abs Maximum", p4_dbl_absmax_op);
  433.  
  434.   /* Tidy up */
  435.  
  436.   p4_shfree((char *) b);
  437.   p4_shfree((char *) a);
  438. }
  439.  
  440.  
  441. void synchronize(type)
  442.      int type;
  443. /*
  444.   Processes block until all have checked in with process 0
  445.   with a message of specified type .. a barrier.
  446. */
  447. {
  448.   int me = p4_get_my_id();
  449.   int nproc = p4_num_total_ids();
  450.   int zero = 0;
  451.   int *msg;
  452.   int msg_len, node, dummy = type;
  453.  
  454.   if (me == zero) {
  455.     for (node=1; node<nproc; node++){       /* Check in */
  456.       msg = (int *) NULL;
  457.       if (p4_recv(&type, &node, (char **) &msg, &msg_len))
  458.     p4_error("synchronize: recv 1 failed", (int) msg);
  459.       p4_msg_free((char *) msg);
  460.     }
  461.     if (p4_broadcast(type, (char *) &dummy, sizeof dummy))
  462.       p4_error("synchronize: broadcast failed",type);
  463.   }
  464.   else {
  465.     if (p4_send(type, zero, (char *) &me, sizeof me))
  466.       p4_error("synchronize: send failed", type);
  467.     msg = (int *) NULL;
  468.     if (p4_recv(&type, &zero, (char **) &msg, &msg_len))
  469.       p4_error("synchronize: recv 2 failed", (int) msg);
  470.     p4_msg_free((char *) msg);
  471.   }
  472. }    
  473.